package ar.edu.caece.compiler.grammars.sample2.factories;

import ar.edu.caece.compiler.grammars.sample2.grammar.E;
import ar.edu.caece.compiler.grammars.sample2.grammar.E1;
import ar.edu.caece.compiler.grammars.sample2.grammar.F;
import ar.edu.caece.compiler.grammars.sample2.tokens.SampleGrammarSymbol;
import ar.edu.caece.compiler.grammars.sample2.tokens.SampleToken;
import ar.edu.caece.compiler.grammars.sample2.tokens.TokenVisitorInterface;
import ar.edu.caece.compiler.model.LexicalAnalyzer;

//E -> F E1
public class EFactory extends AbstractTokenVisitorFactory{

	private static EFactory INSTANCE;
	
	private FFactory fFactory;
	private TokenVisitorInterface parseF;
	private TokenVisitorInterface parseE1;
	private E1Factory e1Factory;
	
	private Initializer initializer = new Initializer() {

		@Override
		public void init() {
			initializer = NoOperationInitializer.getInstance();
			fFactory = FFactory.getInstance();
			parseF = fFactory.makeVisitor();
			e1Factory = E1Factory.getInstance();
			try {
				parseE1 = e1Factory.makeVisitor();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
	};
	
	public static EFactory getInstance() {
		if(INSTANCE==null) INSTANCE = new EFactory();
		return INSTANCE;
	}
	
	public EFactory(LexicalAnalyzer analizadorLexico) {
		super(analizadorLexico);
	}

	public EFactory() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public TokenVisitorInterface makeChainedVisitor(
			final TokenVisitorInterface siguiente) {
		initializer.init();
		return new TokenVisitorInterface() {

			@Override
			public SampleGrammarSymbol defaultCase(SampleToken llamador, SampleGrammarSymbol param) throws Exception {
				// TODO Auto-generated method stub
				SampleGrammarSymbol result = llamador.execute(fFactory.makeChainedVisitor(siguiente), param);
				if(result instanceof F) {
					System.out.println("Generando un nuevo E");
					return new E ((F) result, (E1) nextToken().execute(parseE1, param)); 
				} 
				else {
					System.out.println("Generando un nuevo " + result.getClass());
					return result;
				}
			}
			
		};
	}

	@Override
	public TokenVisitorInterface makeVisitor() {
		initializer.init();
		initializer.init();
		return new TokenVisitorInterface() {

			@Override
			public SampleGrammarSymbol defaultCase(SampleToken llamador, SampleGrammarSymbol param) throws Exception {
				System.out.println("Generando un nuevo E");
				return new E((F) llamador.execute(parseF, param),(E1) nextToken().execute(parseE1, param));
			}
			
		};
	}
	
	
}
